#include "fig_sfx.h"
#include "fighter.h"
#include "fig_sfx_manager.h"

#include "math/facing.h"
#include "part2d/part2d.h"
#include "num/rand.h"
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros


FIGSfx::FIGSfx(FIGSfx::SFX_TYPES Type) : 
								m_Type(Type),
								m_RotationSpeed(0),
								m_bShouldRandomRotate (true),
								m_Alpha(1.0f),
								m_Scale(1.0f),
								m_pParticle(NULL),
								m_TriggerCount(1),
								m_bShouldDisappearWithCounter(false),
								m_Delay(0.0f)  ,
								m_Rotation(0),
								m_SoundSFXName(FIGSounds::SFX_NONE),
								m_IsPostRender(false),
								m_SkipDrawing(false),
								m_IsTickCreationFinish(false),
								m_IsToSpawnOnce(false),
								m_OffsetScale(1.0f),
								m_IsRenderByOwner(false),
								m_IsRenderAtGround(false),
								m_pOwner(NULL)
{
	
	m_bShouldDisappearWithCounter = true;
	m_DisappearCounter.SetLimit(0.5f);
	m_SpawnSize = math::Vec2(0.0025f,0.0025f);

	// call last
	MapTypeToName();
	
}

FIGSfx::~FIGSfx()
{
	Clear();
}

void	FIGSfx::Render(const math::Vec2& Offset,float Scale)
{
	if(!m_IsAlive)
		return;

	if(m_Delay > 0)
		return;

	if(m_SkipDrawing)
		return;

	math::Vec2 TempOffset;
	if(m_IsPostRender)
		TempOffset = math::Vec2(0,0);
	else 
		TempOffset = Offset;

	TempOffset *= m_OffsetScale;

    Scale = Scale *  (m_Scale );
	if(m_pParticle)
	{
		m_pParticle->Render(-TempOffset ,
                             m_Scale
                             );
		
	}
	else
	{
		m_Sprite.m_Pos = m_Pos + TempOffset + m_RandomMovePos;
		m_Sprite.m_Size = m_Size * Scale;
		m_Sprite.m_Rotation = m_Rotation;
		m_Sprite.m_Color = ColorfRGBA(1.0f,1.0f,1.0f,m_Alpha);
		m_Sprite.RenderRotated();

	}
}


void	FIGSfx::SetPoition(const math::Vec2& Pos)
{
	m_Pos = Pos;
	if(m_pParticle)
		m_pParticle->SetPos(m_Pos);
}

void	FIGSfx::RenderDebug(const math::Vec2& Offset,float Scale)
{

}

void	FIGSfx::Tick(float dt)
{
	if(!m_IsAlive)
		return;

	if(m_Delay > 0)
	{
		m_Delay -= dt;		
		if(m_Delay <= 0)
		{
			if(m_pParticle)
			{
				m_pParticle->Clear();
				//for(int i = 0; i < m_TriggerCount; i++)
				//	m_pParticle->TickCreation(10.0f, m_Pos - (m_SpawnSize * 0.5f) , m_SpawnSize);
			}
			if(m_SoundSFXName != FIGSounds::SFX_NONE)
				FIGSounds::Instance().PlaySoundSFX(m_SoundSFXName);	
		}
		
		return;
	}

	if( m_bShouldDisappearWithCounter )
	{
		m_DisappearCounter.Tick(dt);
		if( m_DisappearCounter.IsReady())
		{
			//m_IsAlive = false;
			m_IsTickCreationFinish = true;
			//return;
		}
		
	}
	else
	{
		bool test = true;
	}


	if(m_bShouldRandomRotate)
		m_Rotation += (m_RotationSpeed * dt);
	
	
	if(m_pParticle)
	{	
		m_pParticle->Tick(dt);		

		if(!m_IsToSpawnOnce && !m_IsTickCreationFinish)
		{
			m_pParticle->TickCreation(dt, (m_Pos - (m_SpawnSize * 0.5f)) / m_Scale  , m_SpawnSize);
		}
		
		if(m_IsTickCreationFinish)
		{
			m_IsAlive = m_pParticle->IsActive();
			if(!m_IsAlive)
				bool Test = true;
		}
			
	}
	else
	{
		m_RandomMovePos += (m_RandomDir * dt);
		m_Alpha -= dt;		

		if(!m_Sprite.Tick(dt))
		{
			m_IsAlive = false;
			m_pOwner = NULL;
		}
		
	}


	
}


void	FIGSfx::Clear()
{
	UTIL_SAFE_DELETE(m_pParticle);	
}


void		FIGSfx::Load(const std::string& Name)
{
  	m_Sprite.Create(Name);
	m_Size = m_Sprite.m_Size;
}

void		FIGSfx::ParticleLoad(const std::string& Name,int	TriggerCount)
{
	FIGSfx* pCacheSfx = FIGSFXManager::Instance().GetCacheSfx(m_Type);
	m_TriggerCount = TriggerCount;
	if(pCacheSfx)
	{
		m_pParticle = pCacheSfx->m_pParticle->Clone();		
		return;
	}          	 

	m_pParticle = new part2d::Part2D();
	m_pParticle->Load(Name);
	
}

FIGSfx*		FIGSfx::ReSpawn(		  const math::Vec2& Pos, 
									  float ScaleSize,
									  float Rotation,
									  FIGSounds::SOUND_NAMES SFXName,
									  bool	bIsRegen
									 
									  )
{
	m_pOwner = NULL;
	m_IsRenderAtGround = false;
	m_IsRenderByOwner = false;
	m_IsPostRender = false;
	m_SkipDrawing = false;
	m_SoundSFXName = SFXName;
	if(m_SoundSFXName != FIGSounds::SFX_NONE)
		FIGSounds::Instance().PlaySoundSFX(m_SoundSFXName);	

	if(m_Scale != ScaleSize)
	{
		int test = 1;
	}
	m_Scale = ScaleSize;
	m_Pos = Pos;
	m_Rotation = Rotation;
	float Scale = Fighter::Instance().GetScale();
	Scale = Scale * m_Scale;
	m_RandomMovePos = math::Vec2(0,0);
	
	if(m_Type > CRAFT_PIECES)		
		Randomize();

	if(m_pParticle)
	{
		// make it finish
		m_pParticle->Clear();		
	}
	
	if(m_pParticle)
	{
		// make it finish
		//m_pParticle->Tick(100.0f);

		math::Vec2 Dir = math::Vec2(0,0);
		if(m_bShouldRandomRotate)
		{
			Dir = math::Facing::VectorFromAngle((float)num::RAND32::Instance().RandInt(0,364));
			Dir *= 0.1f;
		}
		else
		{
			math::Facing::VectorFromAngle(-45);
			Dir *= 0.1f;
		}
			
		if(m_bShouldRandomRotate || m_Rotation > 0)
		{
				
			for(int j = 0; j < m_TriggerCount; j++)
			{
				if(m_bShouldRandomRotate)
				{
					Dir = math::Facing::VectorFromAngle((float)num::RAND32::Instance().RandInt(0,364));					
				}
				else
				{
					Dir = math::Facing::VectorFromAngle(m_Rotation);					
				}
					Dir *= 0.03f;

				
				//m_pParticle->TriggerParticleSet(1, m_Pos    ,Dir);
			}
		}		
		//else
			//m_pParticle->TriggerParticleSet(m_TriggerCount, m_Pos  );
		
	}


	m_IsAlive = true;
	m_IsTickCreationFinish = false;
	if(m_pParticle)
	{
		if(m_IsToSpawnOnce)
			m_pParticle->TickCreation(10.0f, (m_Pos - (m_SpawnSize * 0.5f)) / m_Scale  , m_SpawnSize);			
		else
			m_pParticle->Clear();
	}

	if(!bIsRegen && m_bShouldDisappearWithCounter)
		m_DisappearCounter.Reset();

	m_IsTickCreationFinish = false;



	return this;
}




void		FIGSfx::Randomize()
{
	
	m_Alpha = 1.0f;

	m_RotationSpeed =  num::RAND32::Instance().RandFloat( 180.0f,359.0f);
	if(num::RAND32::Instance().RandInt(0,1) == 0)
		m_RotationSpeed  *= -1;

	m_RandomDir = math::Vec2(num::RAND32::Instance().RandFloat( -1.0f,1.0f),
							 num::RAND32::Instance().RandFloat( -1.0f,1.0f));

	m_RandomDir *= num::RAND32::Instance().RandFloat( 0.1f,0.15f);
	m_DisappearCounter.SetLimit(num::RAND32::Instance().RandFloat( 0.25f,0.35f));
	
}

void	FIGSfx::FollowMe(const math::Vec2& Pos)
{
	m_Pos = Pos;
	if(m_pParticle)
		m_pParticle->SetPos(Pos / Fighter::Instance().GetScale() );
}

void	FIGSfx::ToDie()
{
	 m_IsAlive = false;
	 m_pOwner = NULL;
	 if(m_pParticle)
		 m_pParticle->Tick(100.0f);	// make it finish

}

void		FIGSfx::MapTypeToName()
{
	switch(m_Type)
	{
		// explode
		case  EXPLODING_TYPE_NORMAL:			
			ParticleLoad("effects/fig_beforeexplode.p2d",1);			
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 0.5f;				
			//m_IsToSpawnOnce = true;
		break;           

		case EXPLODING_TYPE_EXPLODEBANG:
			ParticleLoad("effects/fig_explode_bang.p2d",1);
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 0.5f;	
			m_IsToSpawnOnce = true;
			break;

		case EXPLODING_TYPE_AFTEREXPLODE:
			ParticleLoad("effects/fig_afterexplode.p2d",1);
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter = 0.5f;				
			
		break;

		case EXPLODING_VERYBIG:
			ParticleLoad("effects/fig_bossexplode_idol_0_burst.p2d",1);			
			m_DisappearCounter.SetLimit(1.5f);
			m_IsToSpawnOnce = false;
			//m_bShouldRandomRotate = true;
			break;

		case EXPLODING_PLAYER:
			ParticleLoad("effects/fig_playerexplode_idol_2_burst.p2d", 1);			
			m_DisappearCounter.SetLimit(0.9f);
			
			break;

		case  EXPLODING_TYPE_SMALLHIT:
  			ParticleLoad("effects/fig_smallhit.p2d", 1);						
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter.SetLimit(0.35f);		
		break;

		case EXPLODING_TYPE_ROKETHIT:
			ParticleLoad("effects/fig_rocket_hit_bang.p2d",1);			
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter.SetLimit(0.2f);
			m_bShouldRandomRotate = true;	
			m_IsToSpawnOnce = true;
		break;

		case EXPLODING_ROKETSMOKE:
			ParticleLoad("effects/fig_smoketrail_ice_hit.p2d",1);
			m_bShouldRandomRotate = true;
			m_bShouldDisappearWithCounter = false;
			

		break;

		case EXPLODING_BONESMOKE:
			ParticleLoad("effects/fig_bone_smoke_trail.p2d",1);
			m_bShouldRandomRotate = false;
			m_bShouldDisappearWithCounter = false;			
			
			break;

		case PICKUP_STAR:
			ParticleLoad("effects/fig_starpickup_popup_fx_1.p2d",1);
			m_bShouldRandomRotate = false;
			break;

		case PICKUP_BULEWEAPON:
			ParticleLoad("effects/fig_pickup_blueweapon_idol_1_charge.p2d",1);			
			m_bShouldRandomRotate = false;
			break;

		case PICKUP_GREENWEAPON:			
			ParticleLoad("effects/fig_pickup_greenweapon_idol_4_charge.p2d",1);						
			m_bShouldRandomRotate = false;
			break;

		case PICKUP_REDWEAPON:
			ParticleLoad("effects/fig_pickup_redweapon_idol_0_charge.p2d",1);						
			m_bShouldRandomRotate = false;
			break;

		case CRAFT_PIECES_TRIANGLE_FRAME:
			Load("Triangle_frame");			
			Randomize();
			m_bShouldRandomRotate = false;
		break;

		case CRAFT_PIECES_TRIANGLE_MAIN:
			Load("Triangle_1");
			m_bShouldRandomRotate = true;
			Randomize();
		break;

		// pickup trial
		case PICKUP_TRAIL:

			ParticleLoad("effects/fig_pickuptrail_power9.p2d",1);
			m_bShouldRandomRotate = false;
			m_bShouldDisappearWithCounter = false;
		break;
		// BOMB
		case PLAYER_BOMB:
			ParticleLoad("effects/fig_bomb_power7.p2d",1);		
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter.SetLimit(1.5f);			
		break;

		case EXPLODING_SPACEROCK:
			ParticleLoad("effects/fig_stone_break.p2d",1);
			m_bShouldRandomRotate = false;
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter.SetLimit(0.9f);			
			m_IsToSpawnOnce = true;
			m_SpawnSize = math::Vec2(0.025f,0.025f);

		break; 

		case BULLET_FIRE:
			ParticleLoad("effects/fire_trail.p2d",1);
			m_bShouldDisappearWithCounter = false;
			m_DisappearCounter.SetLimit(100.0f);
			m_bShouldRandomRotate = false;
		break;

		case BULLET_GUARDIAN:
			ParticleLoad("effects/fig_guardianbullet_power3.p2d",1);
			m_bShouldDisappearWithCounter = false;
			m_DisappearCounter.SetLimit(100.0f);
			m_bShouldRandomRotate = false;
		break;	

		case PICKUP_ORB:
			ParticleLoad("effects/fig_pickup_orb_power3.p2d",1);
			m_bShouldRandomRotate = false;
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter.SetLimit(1.0f);			
		break;

		case PICKUP_TO_UI:
			ParticleLoad("effects/fig_pickuptoui_hintpopup_fx.p2d",1);
			m_bShouldRandomRotate = false;
			m_bShouldDisappearWithCounter = true;
			m_DisappearCounter.SetLimit(1.0f);
			m_IsPostRender = true;	
			m_OffsetScale = 0;
		break;		

		case TWINKLE1:

			ParticleLoad("effects/twinkle.p2d",1);
			m_bShouldDisappearWithCounter = false;
			m_DisappearCounter.SetLimit(1000.0f);			
			m_bShouldRandomRotate = false;
		break;

		case TWINKLE2: 
			ParticleLoad("effects/twinkle2.p2d",1);
			m_bShouldDisappearWithCounter = false;
			m_DisappearCounter.SetLimit(1000.0f);			
			m_bShouldRandomRotate = false;

		break;
		case SPACE_DUST:
			ParticleLoad("effects/fig_space_dust_watertrap.p2d",1);
			m_bShouldDisappearWithCounter = false;
			m_DisappearCounter.SetLimit(1000.0f);			
			m_bShouldRandomRotate = false;
		break;

		

		default:
			break;

	}
}


